﻿using System;
using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Web;

namespace SSO
{
    public class HttpBot
    {
        public static HttpResult Get(string url, X509Certificate cert = null, string cookie = null)
        {
            var request = Create(url);

            if (!string.IsNullOrWhiteSpace(cookie))
                request.Headers.Add("Cookie", cookie);

            if (cert != null)
                request.ClientCertificates.Add(cert);

            return Connect(request);
        }

        private static HttpWebRequest Create(string url)
        {
            var request = WebRequest.CreateHttp(url);
            request.AllowAutoRedirect = false;
            request.Timeout = 15 * 1000;

            return request;
        }

        private static HttpResult Connect(HttpWebRequest request)
        {
            var rs = new HttpResult();
            int retry = 0;
            while (retry < 3)
            {
                try
                {
                    using (var response = request.GetResponse())
                    {
                        rs.Status = (int)((HttpWebResponse)response).StatusCode;
                        rs.Cookie = response.Headers["Set-Cookie"];
                        rs.Location = response.Headers["Location"];
                        rs.Body = ReadAll(response);
                    }
                    break;
                }
                catch (WebException e)
                {
                    retry++;
                    if (retry < 3)
                        continue;

                    var response = e.Response;
                    if (response != null)
                    {
                        rs.Status = (int)((HttpWebResponse)response).StatusCode;
                        rs.Cookie = response.Headers["Set-Cookie"];
                        rs.Location = response.Headers["Location"];
                        rs.Body = ReadAll(response);
                    }
                    else
                    {
                        rs.Status = 600;
                        rs.Body = e.Message;
                    }
                }
            }
            return rs;
        }

        public static HttpResult Post(string url, X509Certificate cert = null, string cookie = null, string payload = null)
        {
            var request = Create(url);
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            //request.Referer = "https://accounts.sap.com/saml2/idp/usso/sap?sp=www.successfactors.com";
            //request.Headers.Add("Origin", "https://accounts.sap.com");
            //request.UserAgent = "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36";
            //request.Accept = "text/html";

            if (!string.IsNullOrWhiteSpace(cookie))
                request.Headers.Add("Cookie", cookie);

            if (cert != null)
                request.ClientCertificates.Add(cert);

            try
            {
                if (payload != null)
                {
                    var buffer = Encoding.UTF8.GetBytes(payload);
                    request.GetRequestStream().Write(buffer, 0, buffer.Length);
                }
            }
            catch (Exception e)
            {
                var rs = new HttpResult();
                rs.Status = 600;
                rs.Body = e.Message;
                return rs;
            }

            return Connect(request);
        }

     

        private static string ReadAll(WebResponse response)
        {
            try
            {
                using (var reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                {
                    return reader.ReadToEnd();
                }
            }
            catch (Exception e)
            {
                return "Error: " + e.Message;
            }

        }
    }
}